"use strict"

/**
 * 数据劫持
 * */ 
class Observer{
    constructor(vm) {
        this.$vm = vm

        this.dataBinding(this.$vm.$data)
    }

    // 数据绑定
    dataBinding(data) {
        const self = this
        Object.keys(data).forEach((key) => {
            const dep = new Dep(this.$vm)
            let value = data[key]

            Object.defineProperty(data, key, {
                configurable: true,
                enumerable: true,
                get() {
                    if (Dep.target) dep.addSubscriber(Dep.target)
                    return value
                },
                set(newValue) {
                    // 值未变更时，直接返回
                    if (newValue === value) return
                    
                    if (utils.isObject(newValue)) {
                        // 值为对象时，迭代的进行数据绑定
                        self.dataBinding(newValue)
                    }

                    value = newValue
                    dep.notice(value)
                }
            })

            if (utils.isObject(data[key])) {
                // 值为对象时，迭代的进行数据绑定
                this.dataBinding(data[key])
            }
        })
    }
}